package com.wisdytech.linkdcs.configuration.service.impl;

import com.alibaba.fastjson.JSON;
import com.wisdytech.common.bean.ConfigurationData;
import com.wisdytech.common.enums.ConfigurationType;
import com.wisdytech.common.enums.NgDataType;
import com.wisdytech.common.exception.ConfigurationException;
import com.wisdytech.common.handler.BaseService;
import com.wisdytech.linkdcs.configuration.dao.ITtEqConfigurationDao;
import com.wisdytech.linkdcs.configuration.model.TtEqConfiguration;
import com.wisdytech.linkdcs.configuration.service.IConfigurationDesignService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

@Service("configurationDesignService")
@Transactional
public class ConfigurationDesignServiceImpl extends BaseService<ITtEqConfigurationDao, TtEqConfiguration> implements IConfigurationDesignService {


    private static final Logger logger = LoggerFactory.getLogger(ConfigurationDesignServiceImpl.class);

    /**
     * scada 文件目录地址
     */
    @Value("${scada.path}")
    private String scadaPath;


    @Resource
    private ITtEqConfigurationDao ttEqConfigurationDao;

    @Override
    public Map<String, Object> getBasicData(String level, String baseNo, String factory) {
        Map<String, Object> data = new HashMap<>();
        // 国家级和省级
        if ("0".equals(level)) {
            //基地总数
            data.put("baseNum", 2);
        }
        if ("1".equals(level)) {
            //基地总数
            data.put("baseNum", 1);
        }
        // 不是产线车间级加入厂区总数
        if (!"3".equals(level)) {
            data.put("factoryNum", 2);
        }
        // 车间总数
        data.put("shopNum", ttEqConfigurationDao.selectShopNum(null));
        // 产线总数
        data.put("lineNum", ttEqConfigurationDao.selectLineNum(null));
        if (StringUtils.isBlank(level)) {
            data.put("equipNum", ttEqConfigurationDao.selectEquipNum(null));
            data.put("collectNum", ttEqConfigurationDao.selectCollectNum(null));
        } else if (StringUtils.isNotBlank(level) && "3".equals(level) && "1".equals(factory)) {
            Map<String, Object> params = new HashMap<>();
            params.put("factoryId", "297e9be760bc1f810160c5106f320351");
            data.put("collectNum", ttEqConfigurationDao.selectCollectNum(params));
            data.put("equipNum", ttEqConfigurationDao.selectEquipNum(params));
        } else if (StringUtils.isNotBlank(level) && "3".equals(level) && "2".equals(factory)) {
            Map<String, Object> params = new HashMap<>();
            params.put("factoryId", "297e9be760bc1f810160c13368910261");
            data.put("collectNum", ttEqConfigurationDao.selectCollectNum(params));
            data.put("equipNum", ttEqConfigurationDao.selectEquipNum(params));
        } else {
            data.put("collectNum", ttEqConfigurationDao.selectCollectNum(null));
            data.put("equipNum", ttEqConfigurationDao.selectEquipNum(null));
        }
        if ("2".equals(baseNo)) {
            data.put("factoryNum", 1);
            data.put("shopNum", 0);
            data.put("lineNum", 0);
            data.put("collectNum", 0);
            data.put("equipNum", 0);
        }
        System.out.println(JSON.toJSONString(data));
        return data;
    }

    @Override
    public Map<String, Object> getHcAndBdEquipStatusInfo(String factoryId, String columnNo) {
        Map<String, Object> data = new HashMap<>();
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.isNotBlank(factoryId)) {
            params.put("factoryId", factoryId);
        }
        if (StringUtils.isNotBlank(columnNo)) {
            params.put("columnNo", columnNo);
        }
        List<Map<String, Object>> list = ttEqConfigurationDao.getHcAndBdEquipStatusInfo(params);
        Map<String, List<Map<String, Object>>> groups = list.stream().collect(Collectors.groupingBy(map -> map.get("status") + ""));
        Map<String, Object> totalStatus = new HashMap<>();
        groups.forEach((k, v) -> {
            if (k.equals("0")) {
                totalStatus.put("close", v.size());
            }
            if (k.equals("1")) {
                totalStatus.put("running", v.size());
            }
            if (k.equals("2")) {
                totalStatus.put("stop", v.size());
            }
            if (k.equals("3")) {
                totalStatus.put("modify", v.size());
            }
            if (k.equals("4")) {
                totalStatus.put("alarm", v.size());
            }
        });
        data.put("totalStatus",totalStatus);
        data.put("equipStatus",list);
        return data;
    }

    @Override
    public List<Map<String, Object>> getShopAndLines(String key) {
        List<Map<String, Object>> data = new ArrayList<>();
        List<Map<String, Object>> shops = ttEqConfigurationDao.getShopsByFactoryId(key);
        List<Map<String, Object>> lines = ttEqConfigurationDao.getLinesByFactoryId(key);
        data.addAll(shops);
        data.addAll(lines);
        return data;
    }

    @Override
    public List<Map<String, Object>> getEquipCodes() {
        return this.ttEqConfigurationDao.getEquipCodes();
    }

    @Override
    public List<Map<String, Object>> getEquipParams(String equipNo) {
        if (StringUtils.isNotBlank(equipNo)) {
            return this.ttEqConfigurationDao.getEquipParams(equipNo);
        } else {
            throw new ConfigurationException(NgDataType.EQUIP_ERROR.getName(),
                    NgDataType.EQUIP_ERROR.getCode());
        }
    }

    @Override
    public List<Map<String, Object>> getFiles(String dir, String types) {
        logger.info("dir is :{}", dir);

        File dirFile = new File(scadaPath);

        List<String> typeLists = Arrays.asList(types.split(","));

        List<File> fileList = getFilesList(scadaPath + "/" + dir, typeLists);

        List<Map<String, Object>> list = new ArrayList<>();
        for (File file : fileList) {
            Map<String, Object> map = new HashMap<>();
            map.put("fileName", file.getName());
            //截取掉开始路径
            map.put("filePath", file.getPath().replace(dirFile.getPath(), ""));
            list.add(map);
        }
        return list;
    }

    private List<File> getFilesList(String path, List<String> type) {
        //目标集合fileList
        List<File> fileLists = new ArrayList<>();
        File file = new File(path);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files == null) {
                return fileLists;
            }
            for (File fileIndex : files) {
                //如果这个文件是目录，则进行递归搜索
                if (fileIndex.isDirectory()) {
                    fileLists.addAll(getFilesList(fileIndex.getPath(), type));
                } else {
                    //如果文件是普通文件，则将文件句柄放入集合中
                    String name = fileIndex.getName();
                    //文件名称
                    String fileTypeName = name.substring(name.lastIndexOf(".") + 1, name.length());
                    if (type.contains(fileTypeName)) {
                        fileLists.add(fileIndex);
                    }

                    //根据类型判断
                	/*if(ConfigurationFileType.JS.getCode().equals(type)) {
                		if(fileIndex.getName().endsWith(".js")) {
                			fileLists.add(fileIndex);
                		}
                        	
                	}else if(ConfigurationFileType.IMG.getCode().equals(type)) {
                		if(fileIndex.getName().endsWith(".jpg")||
                				fileIndex.getName().endsWith(".png")||
                				fileIndex.getName().endsWith(".jpeg")||
                				fileIndex.getName().endsWith(".svg")) {
                			fileLists.add(fileIndex);
                		}
                	}else {
                		//类型错误
                		throw new ConfigurationException(NgDataType.FILE_TYPE_ERROR.getName(),
                    			NgDataType.FILE_TYPE_ERROR.getCode());
                	}*/


                }
            }
        }
        return fileLists;
    }

    @Override
    public ConfigurationData getFileContent(String fileKey, String name, String type) {
        if (ConfigurationType.USER_CONTROL.getCode().equals(type)) {
            if (StringUtils.isBlank(name)) {
                throw new ConfigurationException(NgDataType.FILE_PARAM_ERROR.getName(),
                        NgDataType.FILE_PARAM_ERROR.getCode());
            }
            File file = new File(scadaPath + "/" + name);
            if (!file.exists()) {
                throw new ConfigurationException(NgDataType.FILE_UNFIND.getName(),
                        NgDataType.FILE_UNFIND.getCode());
            }

            Long filelength = file.length();
            byte[] fileContent = new byte[filelength.intValue()];
            FileInputStream in = null;
            try {
                in = new FileInputStream(file);
                in.read(fileContent);
                return new ConfigurationData(new String(fileContent, "UTF-8"), null, null);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new ConfigurationException(NgDataType.FILE_UNFIND.getName(),
                        NgDataType.FILE_UNFIND.getCode());
            } catch (IOException e) {
                e.printStackTrace();
                throw new ConfigurationException(NgDataType.FILE_ERROR.getName(),
                        NgDataType.FILE_ERROR.getCode());
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        throw new ConfigurationException(NgDataType.FILE_ERROR.getName(),
                                NgDataType.FILE_ERROR.getCode());
                    }
                }
            }

        } else {
            if (StringUtils.isBlank(fileKey)) {
                throw new ConfigurationException(NgDataType.SCADA_ERROR.getName(),
                        NgDataType.SCADA_ERROR.getCode());
            }
            TtEqConfiguration ttEqConfiguration = ttEqConfigurationDao.selectById(fileKey);
            if (null == ttEqConfiguration) {
                throw new ConfigurationException(NgDataType.SCADA_ERROR.getName(),
                        NgDataType.SCADA_ERROR.getCode());
            }

            return new ConfigurationData(ttEqConfiguration.getJsonFile(), ttEqConfiguration.getCenter(), ttEqConfiguration.getEye());
        }
    }

    @Override
    public boolean saveFile(String path, String fileKey, String name, String content, String type, String equipNo, String center, String eye) {

        //保存scada数据
        if (ConfigurationType.SCADA_EDITOR.getCode().equals(type)) {
            if (StringUtils.isBlank(fileKey)) {
                throw new ConfigurationException(NgDataType.SCADA_ERROR.getName(),
                        NgDataType.SCADA_ERROR.getCode());
            }

            TtEqConfiguration ttEqConfiguration = new TtEqConfiguration();
            ttEqConfiguration.setPkId(fileKey);
            ttEqConfiguration.setJsonFile(content);
            ttEqConfiguration.setJsonEquips(equipNo);
            ttEqConfiguration.setCenter(center);
            ttEqConfiguration.setEye(eye);
            ttEqConfigurationDao.saveJson(ttEqConfiguration);

            return true;


        } else {//保存json 文件

            if (StringUtils.isBlank(path) || StringUtils.isBlank(name)) {
                throw new ConfigurationException(NgDataType.FILE_PARAM_ERROR.getName(),
                        NgDataType.FILE_PARAM_ERROR.getCode());
            }

            File file = new File(scadaPath + "/" + path + "/" + name);
            FileWriter fw = null;
            PrintWriter pw = null;
            try {
                fw = new FileWriter(file, false);
                pw = new PrintWriter(fw);
                pw.println(content);
                pw.flush();
                return true;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new ConfigurationException(NgDataType.FILE_UNFIND.getName(),
                        NgDataType.FILE_UNFIND.getCode());
            } catch (IOException e) {
                e.printStackTrace();
                throw new ConfigurationException(NgDataType.FILE_ERROR.getName(),
                        NgDataType.FILE_ERROR.getCode());
            } finally {
                if (pw != null) {
                    pw.close();
                }
                if (fw != null) {
                    try {
                        fw.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        throw new ConfigurationException(NgDataType.FILE_ERROR.getName(),
                                NgDataType.FILE_ERROR.getCode());
                    }
                }
            }

        }
    }

    @Override
    public boolean checkControlName(String dir, String name) {
        String path = scadaPath + "/" + dir + "/" + name;
        File file = new File(path);
        return file.exists();
    }

    @Override
    public void uploadFile(byte[] file, String filePath, String fileName) {
        File targetFile = new File(scadaPath + "/" + filePath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(scadaPath + "/" +

                    filePath + fileName);
            out.write(file);
            out.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                if (null != out)
                    out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    @Override
    public List<Map<String, Object>> getItemFils(String dir) {

        File file = new File(scadaPath + File.separator + dir);
        File scadaFile = new File(scadaPath);

        if (!file.exists() || !file.isDirectory()) {
            return null;
        }
        File[] files = file.listFiles();

        Map<String, String> svgMaps = new HashMap<>();
        Map<String, String> jsonMaps = new HashMap<>();

        List<Map<String, Object>> result = new ArrayList<>();

        if (files == null) {
            logger.warn("No files in the directory[{}]", scadaPath + File.separator + dir);
            return result;
        }
        for (File file1 : files) {
            if (file1.isDirectory()) {
                continue;
            }

            String name = file1.getName().substring(0, file1.getName().lastIndexOf("."));

            if (file1.getName().endsWith(".svg")) {
                svgMaps.put(name, file1.getPath().replace(scadaFile.getPath(), ""));
            } else if (file1.getName().endsWith(".json")) {
                jsonMaps.put(name, file1.getPath().replace(scadaFile.getPath(), ""));
            }
        }

        //循环判断svg与json对应关系
        Set<String> keys = svgMaps.keySet();

        for (String key : keys) {
            if (jsonMaps.containsKey(key)) {
                Map<String, Object> okData = new HashMap<>();
                okData.put("icon", svgMaps.get(key));
                okData.put("img", jsonMaps.get(key));
                result.add(okData);
            }
        }


        return result;
    }
}
